package com.bt.att;

import com.bt.att.dao.PhoneDao;
import com.bt.att.model.Call;
import com.bt.att.model.Message;
import com.bt.att.model.Phone;
import org.springframework.beans.factory.annotation.Autowired;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

/**
 * TableDataScrollPane.
 *
 * @author Zakir Magdum
 */
public class TableDataScrollPane extends JScrollPane {
    private static final boolean DEBUG = true;
    private static final DateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy hh:mm:ssaa");
    private JTable table;
    private Phone phone;
    private boolean isCall = true;
    private Date start;
    private Date end;
    private String[] columnNames = {"Time",
            "Number",
            "Duration",
            "Incoming?",
            "Cost"};
    private Object[][] data = {
            {"Kathy", "Smith",
                    "Snowboarding", new Integer(5), new Boolean(false)},
            {"John", "Doe",
                    "Rowing", new Integer(3), new Boolean(true)},
            {"Sue", "Black",
                    "Knitting", new Integer(2), new Boolean(false)},
            {"Jane", "White",
                    "Speed reading", new Integer(20), new Boolean(true)},
            {"Joe", "Brown",
                    "Pool", new Integer(10), new Boolean(false)}
    };

    @Autowired
    private PhoneDao dao;

    public void init() {
        table = new JTable(new MyTableModel(this));
        setViewportView(table);
    }

    public void setDataFilter(Phone phone, boolean isCall, Date start, Date end) {
        this.phone = phone;
        this.isCall = isCall;
        this.start = start;
        this.end = end;
        if (isCall) {
            List<Call> calls = dao.getCalls(phone.getNumber(), start, end);
            data = new Object[calls.size()][columnNames.length];
            for (int ii = 0; ii < calls.size(); ii++) {
                Call call = calls.get(ii);
                data[ii][0] = dateFormat.format(call.getTimestamp());
                data[ii][1] = call.getTo().getNumber();
                data[ii][2] = call.getDuration();
                data[ii][3] = call.isIncoming();
                data[ii][4] = call.getTotalCharge();
            }
        } else {
            List<Message> messages = dao.getMessages(phone.getNumber(), start, end);
            data = new Object[messages.size()][columnNames.length];
            for (int ii = 0; ii < messages.size(); ii++) {
                Message message = messages.get(ii);
                data[ii][0] = dateFormat.format(message.getTimestamp());
                data[ii][1] = message.getTo().getNumber();
                data[ii][2] = message.getMsgKB();
                data[ii][3] = message.isIncoming();
                data[ii][4] = message.getTotalCharge();
            }
        }
        table.setModel(new MyTableModel(this));
    }

    class MyTableModel extends AbstractTableModel {
        private TableDataScrollPane pane;

        public MyTableModel(TableDataScrollPane pane) {
            this.pane = pane;
        }

        public int getColumnCount() {
            return pane.columnNames.length;
        }

        public int getRowCount() {
            return pane.data.length;
        }

        public String getColumnName(int col) {
            return pane.columnNames[col];
        }

        public Object getValueAt(int row, int col) {
            return pane.data[row][col];
        }

        /*
         * JTable uses this method to determine the default renderer/
         * editor for each cell.  If we didn't implement this method,
         * then the last column would contain text ("true"/"false"),
         * rather than a check box.
         */
        public Class getColumnClass(int c) {
            return getValueAt(0, c).getClass();
        }

        /*
         * Don't need to implement this method unless your table's
         * editable.
         */
        public boolean isCellEditable(int row, int col) {
            //Note that the data/cell address is constant,
            //no matter where the cell appears onscreen.
            if (col < 2) {
                return false;
            } else {
                return true;
            }
        }

        /*
        * Don't need to implement this method unless your table's
        * data can change.
        */
        public void setValueAt(Object value, int row, int col) {
            if (DEBUG) {
                System.out.println("Setting value at " + row + "," + col
                        + " to " + value
                        + " (an instance of "
                        + value.getClass() + ")");
            }

            pane.data[row][col] = value;
            fireTableCellUpdated(row, col);

            if (DEBUG) {
                System.out.println("New value of data:");
                printDebugData();
            }
        }

        private void printDebugData() {
            int numRows = getRowCount();
            int numCols = getColumnCount();

            for (int i = 0; i < numRows; i++) {
                System.out.print("    row " + i + ":");
                for (int j = 0; j < numCols; j++) {
                    System.out.print("  " + pane.data[i][j]);
                }
                System.out.println();
            }
            System.out.println("--------------------------");
        }
    }

}
